#include "stdafx.h"
#include "ASpriteInstance.h"
//#include "Core/Def.h"

const f32 cScaledSpriteFPS = 10 / 10.0f;

ASpriteInstance::ASpriteInstance( ASprite* pCurrentSprite ):
                 m_pCurrentSprite(0),
                 m_2DScale_X(100),
                 m_2DScale_Y(100),
				 m_bAchievable(true),
				 m_bAnimFinished(false),
				 m_bCurAnimFinished(false)
{
	m_nX = 0;
	m_nY = 0;
	SetASprite( pCurrentSprite );

	m_scaleX = 1.0f;
	m_scaleY = 1.0f;

	Stop();

	m_flippedX = false;
	m_bIsPlaying = false;

	m_fScaleAnim = cScaledSpriteFPS;
}

ASpriteInstance::~ASpriteInstance()
{
    SafeDelete( m_pCurrentSprite );
}

void ASpriteInstance::Stop()
{
	//m_nCurrentAnim = -1;
	m_nCurrentAFrame = 0;
	m_nCurrentFTime = 0;
	m_nCurrentAnimTime = 0;
	//m_nLoop = 0xFFFFFF;
	m_nNextAnim = -1;
}

void ASpriteInstance::SetAnim(int anim, int loop)
{
	Stop();
	m_bIsPlaying = true;
	m_nCurrentAnim = anim;
	m_nLoop = loop;
	m_bAnimFinished = false;
	m_bCurAnimFinished = false;
	m_nCurrentAnimTimeAll = 0;
	for(int i = 0;i<m_pCurrentSprite->GetAFrames(m_nCurrentAnim);i++)
	{
		m_nCurrentAnimTimeAll += m_pCurrentSprite->GetAFrameTime(m_nCurrentAnim,i);
	}
	m_nCurrentAnimTimeAll *= /*cScaledSpriteFPS*/m_fScaleAnim;
}

void ASpriteInstance::SetPosition(int x, int y)
{
	m_nX = x;
	m_nY = y;
}

void ASpriteInstance::SetAchievable(bool achievable)
{
	m_bAchievable = achievable;
}

void ASpriteInstance::SetASprite(ASprite* sprite)
{
    if ( !sprite )
        return;

    SafeDelete( m_pCurrentSprite );

	m_pCurrentSprite = sprite;
    sprite->grab();
}

void ASpriteInstance::StartAnim(ASprite* sprite, int anim, int x, int y, int loop)
{
    if ( !sprite )
        return;
	Stop();

    if ( m_pCurrentSprite != sprite )
    {
        SafeDelete( m_pCurrentSprite );
        m_pCurrentSprite = sprite;
        sprite->grab();
    }

	m_nCurrentAnim = anim;
	m_nX = x;
	m_nY = y;
	m_nLoop = loop;
	m_bIsPlaying = true;
}

void ASpriteInstance::SetTransitionAnim(int anim, int nextAnim)
{
	SetAnim(anim);
	m_nNextAnim = nextAnim;
}

int ASpriteInstance::GetCurrentAnimTimeAll()
{
	
	return m_nCurrentAnimTimeAll;
}

void ASpriteInstance::Update()
{
	if(m_pCurrentSprite == NULL || m_nCurrentAnim < 0)
		return;

	f32 time = (f32)(m_pCurrentSprite->GetAFrameTime(m_nCurrentAnim, m_nCurrentAFrame) * m_fScaleAnim/*cScaledSpriteFPS*/);

	if(time == 0)
	{
		return;
	}

	if (m_nCurrentAFrame == m_pCurrentSprite->GetAFrames(m_nCurrentAnim) - 1)
	{
		m_bCurAnimFinished = true;
	}

	if(!m_bAchievable && m_nCurrentAFrame == m_pCurrentSprite->GetAFrames(m_nCurrentAnim) - 1)
	{
		m_bAnimFinished = true;
		return;
	}


	m_nCurrentFTime++;
	m_nCurrentAnimTime++;

	if(m_nCurrentFTime < time)
    {
        return;
    }

	

	m_nCurrentFTime = 0;
    m_nCurrentAFrame++;
    		
    if(m_nCurrentAFrame >= m_pCurrentSprite->GetAFrames(m_nCurrentAnim))
    {		
		
		if(m_nNextAnim >= 0)
		{
			SetAnim(m_nNextAnim);
		}
		else
		{
			m_nLoop--;
			if(m_nLoop < 0)
			{
				Stop();
				m_bIsPlaying = false;
				m_bCurAnimFinished = true;
			}
			else
			{
				m_nCurrentAFrame	= 0;
				m_nCurrentAnimTime	= 0;
				m_nNextAnim = -1;
			}
		}
	}
}

bool ASpriteInstance::IsAnimOver() const
{
	return (m_nLoop < 0) && m_nCurrentAFrame == 0 && m_nCurrentFTime == 0; 
}

bool ASpriteInstance::IsAnimOver2() const
{
	return m_nCurrentAFrame == 0 && m_nCurrentFTime == 0; 
}

void ASpriteInstance::Draw(EXT_DRAW_INFO* info) const
{
	if(m_pCurrentSprite == NULL || m_nCurrentAnim < 0)
		return;

	m_pCurrentSprite->PaintAFrame(m_nCurrentAnim, m_nCurrentAFrame, m_nX, m_nY,
                                  (m_flippedX ? ASprite::FLAG_FLIP_X : 0), 
                                  0, 
                                  0,
                                  255,
                                  0,
                                  m_2DScale_X,
                                  m_2DScale_Y,
                                  info);
	//TRACE("anim:%d\t x:%d\t y:%d\t\n",m_nCurrentAFrame,m_nX,m_nY);
}


void ASpriteInstance::Draw3D(irr::core::vector3df pos, irr::f32 xscale, irr::f32 yscale, int flags,bool isFaceCamera)
{
	if(m_pCurrentSprite == NULL || m_nCurrentAnim < 0)	return;
	m_pCurrentSprite->PaintAFrame3D(m_nCurrentAnim, 
									m_nCurrentAFrame, 
									m_3DPos,// pos, 
									flags, 
									isFaceCamera,
									xscale, yscale);
}



irr::core::rect<int> ASpriteInstance::GetAnimRect()
{
	if(m_pCurrentSprite == NULL || m_nCurrentAnim < 0)
		return irr::core::rect<int>();

    irr::core::rect<int> rcAnim;// Init to 0,0,0,0 in ctor

    for( int i = 0; i < m_pCurrentSprite->GetAFrames( m_nCurrentAnim ); i++ )
    {
        int nFrame = m_pCurrentSprite->GetAnimFrame( m_nCurrentAnim, i );
        int x = m_pCurrentSprite->GetFrameLeft( nFrame );
        int y = m_pCurrentSprite->GetFrameTop( nFrame );
        irr::core::rect<int> rcCurAnim( x, y,
            x + m_pCurrentSprite->GetFrameWidth(nFrame),
            y + m_pCurrentSprite->GetFrameHeight(nFrame));

        if ( i == 0 )
        {
            rcAnim = rcCurAnim;
        }
        else
        {
            Maximize( rcAnim, rcCurAnim );
        }

    }
    return rcAnim + irr::core::position2d<int>(m_nX, m_nY);
}

